home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / Libraries / VideoToolbox 96.06.15 / VideoToolboxSources / NoiseFill.c < prev    next >
Text File  |  1995-05-27  |  7KB  |  168 lines

  1. /* NoiseFill.c
  2. © 1989-1994 Denis G. Pelli.
  3.     error=NoiseFill(window,&rect,dx,dy,randomPhase); 
  4. Fills the rect in the window with noise. The noise is made up of black & white
  5. checks, each dx pixels wide by dy pixels high. Random phase is optional. (dx and
  6. dy are doubles, and need not be integral. The noise is synthesized with 1-pixel
  7. checks and expanded by CopyBits, which is capable of expansion by non-integral
  8. amounts.)
  9.  
  10.     error=NoiseFillBits(pixmapPtr,&rect,dx,dy,randomPhase);
  11. Same, but accepts a pix/bitmap ptr in place of the window.
  12.  
  13.     error=MakeNoise1(dx,dy,randomPhase,pixmapPtr);
  14. Same, but fills the whole pix/bitmap, i.e. uses pixmapPtr->bounds as the rect.
  15. Obsolete, retained solely for compatibility.
  16.  
  17. We use the current port's ForeColor and BackColor to make the noise. (If
  18. baseAddr==NULL, we share the color table of the current device.) Apple's
  19. GetGWorld and SetGWorld calls are a convenient way of getting, changing, and
  20. restoring the current port and device.
  21.  
  22. If pixmapPtr->baseAddr==NULL then the data area will be allocated for you. You
  23. must set pixmapPtr->bounds and pixmapPtr->pixelSize; the rest of the PixMap
  24. struct will be filled in by NoiseFillBits. It will install a handle to the
  25. current device's color table. The values filled into the fields are necessarily
  26. somewhat arbitrary. For more control, fill in the fields yourself, using
  27. NewPixMap(), and allocate the data area yourself before calling NoiseFillBits().
  28.  
  29. HISTORY:
  30. 6/21/89 dgp    changed frameBytes and bufferBytes to long so that this code won't crash
  31.             if the pixelSize is greater than 1 bit.
  32. 8/5/89 dgp    wrote and installed randU(), which yields two random bytes per call, instead
  33.             of rand() which yields only one, allowing the noise generation to go twice
  34.             as fast.
  35. 3/11/90 dgp    Changed dx and dy from int to double. This allows nonuniform cell size,
  36.             which arises when CopyBits expands by these nonintegral factors. Results
  37.             will be same as before when integral values are supplied.
  38.             Made the cosmetic change of replacing "unsigned long" by "size_t".
  39. 3/20/90    dgp    make compatible with MPW C.
  40. 3/31/90    dgp    set pmVersion to zero for compatibility with QD32
  41. 8/7/90    dgp    Now uses the current ForeColor and BackColor to make the noise.
  42.             For future compatibility, now zeroes the packType, etc. fields.
  43. 10/1/90    dgp    Cosmetic changes: replaced two OffsetRect calls by CenterRectInRect call.
  44. 11/16/90 dgp Added RANDOM_PHASE.
  45. 4/20/91    dgp    Added new MakeNoise1() that accepts a single PixMap, and allocates
  46.             its data area only if baseAddr==NULL, otherwise assuming that it already
  47.             exists. I rewrote MakeNoise() to simply call MakeNoise1() repeatedly.
  48.             MakeNoise() now seems obsolete, but is retained for compatibility with old
  49.             programs.
  50. 4/24/91    dgp    Fixed bug introduced into MakeNoise() on 4/20, which resulted in all the
  51.             PixMaps using the same buffer.
  52. 8/6/91    dgp    Replaced use of randU() by RandFill(), which is twice as fast.
  53. 8/24/91    dgp    Made compatible with THINK C 5.0.
  54. 4/17/92    dgp    Removed hidden assumption that bits->bounds.top and bits->bounds.left
  55.             were both zero. If they were negative MakeNoise1 would allocate too 
  56.             little space, and then overwrite memory and crash.
  57. 4/27/92    dgp    Initialize all remaining fields of the *bits PixMap, and copy the current
  58.             device's color table handle.
  59. 10/22/92 dgp Check for error in CopyBits.
  60. 9/5/94 dgp removed assumption in printf's that int==short.
  61. 11/21/94 dgp in response to note from Marty Wachter, improve centering algorithm, so
  62.             that if dx & dy are integral the final image is made of whole checks.
  63. 11/21/94 dgp renamed NoiseFill.c and added new calling interfaces, analogous to those
  64.             for CopyWindows and CopyBits.
  65. */
  66. #include "VideoToolbox.h"
  67. int MakeNoise1(double dx,double dy,Boolean randomPhase,PixMap *bits)
  68. {
  69.     return NoiseFillBits(bits,&bits->bounds,dx,dy,randomPhase);
  70. }
  71.  
  72. int NoiseFill(CWindowPtr window,Rect *r,double dx,double dy,Boolean randomPhase)
  73. {
  74.     Boolean error,ok;
  75.  
  76.     if(IsGWorldPtr(window)){
  77.         ok=LockPixels(window->portPixMap);
  78.         if(!ok)return 2;
  79.     }
  80.     if(IsGrafPtr(window))
  81.         error=NoiseFillBits((PixMap *)&((WindowPtr)window)->portBits,r,dx,dy,randomPhase);
  82.     else{
  83.         HLock((Handle)window->portPixMap);
  84.         error=NoiseFillBits(*window->portPixMap,r,dx,dy,randomPhase);
  85.         HUnlock((Handle)window->portPixMap);
  86.     }
  87.     if(IsGWorldPtr(window))UnlockPixels(window->portPixMap);
  88.     return error;
  89. }
  90.  
  91. int NoiseFillBits(PixMap *bits,Rect *r,double dx,double dy,Boolean randomPhase)
  92. {
  93.     BitMap buffer,bigBuffer;
  94.     Rect srcRect;
  95.     size_t frameBytes,bufferBytes;
  96.     static const RGBColor blackRGB={0,0,0},whiteRGB={0xffff,0xffff,0xffff};
  97.     RGBColor backRGB,foreRGB;
  98.     int error;
  99.     
  100.     if(dx<=0 || dy<=0)return 3;
  101.     srandU((unsigned int)rand());    /* seed our unsigned random number generator */
  102.     GetBackColor(&backRGB);
  103.     GetForeColor(&foreRGB);
  104.  
  105.     /* allocate buffer BitMap */
  106.     SetRect(&buffer.bounds,0,0,ceil((r->right - r->left)/dx),ceil((r->bottom - r->top)/dy));
  107.     if(randomPhase){
  108.         buffer.bounds.right++;
  109.         buffer.bounds.bottom++;
  110.     }
  111.     buffer.rowBytes=(buffer.bounds.right + 31 & ~31)/8; /* round up to multiple of 32 bits */
  112.     bufferBytes=(size_t) buffer.rowBytes * (size_t) buffer.bounds.bottom;
  113.     buffer.baseAddr=(Ptr) NewPtr(bufferBytes);
  114.     if(buffer.baseAddr == NULL)return 4;
  115.  
  116.     /* allocate bigBuffer BitMap */
  117.     SetRect (&bigBuffer.bounds,0,0,(int)round(buffer.bounds.right*dx),
  118.         (int)round(buffer.bounds.bottom*dy));
  119.     bigBuffer.rowBytes=(bigBuffer.bounds.right + 31 & ~31)/8; /* round up to multiple of 32 bits */
  120.     bigBuffer.baseAddr=(Ptr) NewPtr((size_t) bigBuffer.rowBytes * (size_t) bigBuffer.bounds.bottom);
  121.     if(bigBuffer.baseAddr == NULL){
  122.         DisposePtr(buffer.baseAddr);
  123.         return 5;
  124.     }
  125.     /* if necessary, fill in pixmap's fields and allocate its data area */
  126.     if(bits->baseAddr == NULL){
  127.         // If we're allocating, assume *bits is a PixMap, not a Bitmap.
  128.         bits->hRes=bits->vRes=0x480000;    // 72 dpi
  129.         bits->pmVersion=bits->packType=bits->packSize=0;
  130.         bits->planeBytes=bits->pmReserved=0;
  131.         bits->cmpCount=1;
  132.         bits->cmpSize=bits->pixelSize;
  133.         bits->pmTable=(**(**GetGDevice()).gdPMap).pmTable;
  134.         bits->rowBytes=((bits->bounds.right-bits->bounds.left)*bits->pixelSize + 31 & ~31)/8; /* round up to multiple of 32 bits */
  135.         frameBytes=(size_t) bits->rowBytes * (bits->bounds.bottom-bits->bounds.top);
  136.         bits->rowBytes |= 0x8000;    /* mark it as a PixMap */
  137.         bits->baseAddr=(char *) NewPtr(frameBytes);
  138.         if(bits->baseAddr == NULL)return 6;
  139.     }
  140.     if((size_t)bits->baseAddr%4 != 0L){
  141.         printf("WARNING: Frame buffer address is not long aligned. %s\007\n",__FILE__);
  142.     }
  143.  
  144.     /* create random noise */
  145.     /* First create a random bit image, all bits uncorrelated. */
  146.     RandFill(buffer.baseAddr,bufferBytes);
  147.     /* Now expand image so that each random bit becomes a dx by dy rectangle. */
  148.     RGBBackColor(&whiteRGB);
  149.     RGBForeColor(&blackRGB);
  150.     CopyBits(&buffer,&bigBuffer,&buffer.bounds,&bigBuffer.bounds,srcCopy,NULL);
  151.     error=QDError();
  152.     if(error)printf("MakeNoise1:a: CopyBits error %d\n",error);
  153.     /* Finally copy it into the bit/pixmap, trimming it down to the correct size. */
  154.     RGBBackColor(&backRGB);
  155.     RGBForeColor(&foreRGB);
  156.     srcRect=*r;
  157.     OffsetRect(&srcRect,-srcRect.left,-srcRect.top);
  158.     if(randomPhase) OffsetRect(&srcRect,nrand(dx),nrand(dy));
  159.     else CenterRectInRect(&srcRect,&bigBuffer.bounds);
  160.     CopyBits(&bigBuffer,(BitMap *)bits,&srcRect,r,srcCopy,NULL);
  161.     error=QDError();
  162.     DisposPtr((void *) buffer.baseAddr);
  163.     DisposPtr((void *) bigBuffer.baseAddr);
  164.     return error;
  165. }
  166.  
  167.  
  168.